#pragma once

//作为网络通信的接口

#include<iostream>
#include<memory>
#include<functional>
#include<sys/socket.h>

#include"Socket.hpp"

#include <sys/wait.h>



namespace TcpserverMoudle{

    using namespace SocketMoudle;
    using namespace LogMoudle;

    using tcpHandler_t=std::function<bool(SockPtr,InetAddr)>;
    //只负责IO不对数据进行任何处理

    class Tcpserver
    {
        public:
        Tcpserver(int port):_listensock(std::make_unique<TcpSocket>()),_port(port),_isruning(false)
        {

        }

        void InitServer(tcpHandler_t handler)
        {
            _handler=handler;
            _listensock->BuildTcpSocket(_port);
        }

        void Loop()
        {
            _isruning=true;

            while(_isruning)
            {
                InetAddr clientaddr;
                //接收客户端套接字
                auto sockfd=_listensock->Accepter(&clientaddr);
                if(sockfd==nullptr)continue;

                LOG(Logevel::INFO)<<"get a new cline, cline info : "<<clientaddr.PrintDebug();

                // sockfd->Recv();
                // sockfd->Send();

                pid_t pid=fork();
                if(pid==0)
                {
                    _listensock->Close();
                    
                   if(fork()>0)
                   {
                    exit(0);
                   }
                   _handler(sockfd,clientaddr);
                   exit(0);
                }
                
                sockfd->Close();
                waitpid(pid, nullptr, 0);
            }

            _isruning=false;

        }

        private:
        //一定要有listen套接字
        std::unique_ptr<Socket> _listensock;
        bool _isruning;

        int _port;


        //处理方式
        tcpHandler_t _handler;
    };


}